package com.moon.admin.flowable.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.engine.ManagementService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.impl.persistence.entity.ActivityInstanceEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.moon.admin.flowable.FlowableConstants;
import com.moon.admin.flowable.domain.AddSignTask;
import com.moon.admin.flowable.domain.CompleteTask;
import com.moon.admin.flowable.domain.DelegateTask;
import com.moon.admin.flowable.domain.FlowAttachment;
import com.moon.admin.flowable.domain.RevokeProcessTask;
import com.moon.admin.flowable.domain.StopProcessInstance;
import com.moon.admin.flowable.domain.TurnTask;
import com.moon.admin.flowable.entity.ActCnHistoricProcessEntity;
import com.moon.admin.flowable.mapper.HisFlowableActinstDao;
import com.moon.admin.flowable.mapper.RunFlowableActinstDao;
import com.moon.admin.framework.secure.AuthUtils;
import com.moon.admin.framework.util.MoonException;
import com.moon.admin.framework.util.ToolUtils;
import com.moon.admin.sys.service.SysPostService;

import lombok.extern.slf4j.Slf4j;

/**
 * 流程核心操作
 * @author ninglong
 * @date 2020年7月8日
 */
@Service
@Slf4j
public class FlowableEngineService{

	@Autowired
	private ProcessEngine processEngine;
	@Autowired
	private SysPostService postService;
	@Autowired
	private ManagementService managementService;
	@Autowired
	private RunFlowableActinstDao runFlowableActinstDao;
	@Autowired
	private HisFlowableActinstDao hisFlowableActinstDao;
	@Autowired
	private FlowableBpmnModelService flowableBpmnModelService;
	
	/**
	 * 待签任务
	 */
	public IPage<ActCnHistoricProcessEntity> selectUnClaimProcessList(ActCnHistoricProcessEntity actCnHistoricProcessEntity) {
		List<HistoricTaskInstance> tasks = Lists.newArrayList();
		Set<String> processInstanceIds = new HashSet<String>();
		Map<String,String> processInstanceIdsToTaskId = Maps.newHashMap();
		HistoricTaskInstanceQuery taskQuery = processEngine.getHistoryService().createHistoricTaskInstanceQuery();
		List<String> postIds = postService.getPostListByUserId(AuthUtils.getCurrentUserId()).stream().map(entity->String.valueOf(entity.getId())).collect(Collectors.toList());
		tasks = taskQuery.taskCandidateGroupIn(postIds).unfinished().processUnfinished().list();
		tasks.addAll(taskQuery.taskCandidateUser(String.valueOf(AuthUtils.getCurrentUserId())).unfinished().processUnfinished().list());
		IPage<ActCnHistoricProcessEntity> page = new Page<>(actCnHistoricProcessEntity.getPage(),actCnHistoricProcessEntity.getLimit());
		if (ToolUtils.isEmpty(tasks)) {
			return page;
		}
		for (HistoricTaskInstance hisTask:tasks) {
			processInstanceIds.add(hisTask.getProcessInstanceId());
			Task task = processEngine.getTaskService().createTaskQuery().processInstanceId(hisTask.getProcessInstanceId()).active().singleResult();
			processInstanceIdsToTaskId.put(hisTask.getProcessInstanceId(), task.getId());
		}
		HistoricProcessInstanceQuery processQuery = processEngine.getHistoryService().createHistoricProcessInstanceQuery();
		processQuery.processInstanceIds(processInstanceIds);
		if (ToolUtils.isNotEmpty(actCnHistoricProcessEntity.getName())) {
			processQuery.processInstanceNameLike("%" + actCnHistoricProcessEntity.getName() + "%");
		}
		int total = (int) processQuery.count();
		if(total==0) {
			return page;
		}
		page.setTotal(total);
		List<HistoricProcessInstance> list = processQuery.orderByProcessInstanceStartTime().desc().listPage(actCnHistoricProcessEntity.getStart(),actCnHistoricProcessEntity.getLimit());
		List<ActCnHistoricProcessEntity> records = new ArrayList<ActCnHistoricProcessEntity>();
		for(HistoricProcessInstance entity:list) {
			ActCnHistoricProcessEntity tmpProcess = new ActCnHistoricProcessEntity(entity);
			tmpProcess.setTaskId(processInstanceIdsToTaskId.get(entity.getId()));
			records.add(tmpProcess);
		}
		page.setRecords(records);
		return page;
	} 

	/**
	 * 待办任务
	 */
	public IPage<ActCnHistoricProcessEntity> selectUnfinishedProcessList(ActCnHistoricProcessEntity actCnHistoricProcessEntity) {
		return this.selectHistoricProcessList(actCnHistoricProcessEntity, false);
	}

	/**
	 * 已办任务
	 */
	public IPage<ActCnHistoricProcessEntity> selectFinishedProcessList(ActCnHistoricProcessEntity actCnHistoricProcessEntity) {
		return this.selectHistoricProcessList(actCnHistoricProcessEntity, true);
	}

	/**
	 * 办结任务
	 */
	public IPage<ActCnHistoricProcessEntity> selectCompleteProcessList(ActCnHistoricProcessEntity actCnHistoricProcessEntity) {
		HistoricProcessInstanceQuery processQuery = processEngine.getHistoryService()
				.createHistoricProcessInstanceQuery();
		if (ToolUtils.isNotEmpty(actCnHistoricProcessEntity.getName())) {
			processQuery.processInstanceNameLike("%" + actCnHistoricProcessEntity.getName() + "%");
		}
		processQuery.finished();
		IPage<ActCnHistoricProcessEntity> page = new Page<>(actCnHistoricProcessEntity.getPage(),actCnHistoricProcessEntity.getLimit());
		int total = (int) processQuery.count();
		if(total==0) {
			return page;
		}
		page.setTotal(total);
		List<HistoricProcessInstance> list = processQuery.orderByProcessInstanceStartTime().desc().listPage(actCnHistoricProcessEntity.getStart(),actCnHistoricProcessEntity.getLimit());
		List<String> processInstanceIds = Lists.newArrayList();
		list.stream().forEach(entity->{
			processInstanceIds.add(entity.getId());
		});
		List<Task> tasks = processEngine.getTaskService().createTaskQuery().processInstanceIdIn(processInstanceIds).active().list();
		Map<String,String> tasksMap = tasks.stream().collect(Collectors.toMap(Task::getProcessInstanceId, Task::getId));
		List<ActCnHistoricProcessEntity> records = new ArrayList<ActCnHistoricProcessEntity>();
		for(HistoricProcessInstance entity:list) {
			ActCnHistoricProcessEntity tmpProcess = new ActCnHistoricProcessEntity(entity);
			tmpProcess.setTaskId(tasksMap.get(entity.getId()));
			records.add(tmpProcess);
		}
		page.setRecords(records);
		return page;
	}
	
	/**
	 * 我发起的流程
	 */
	public IPage<ActCnHistoricProcessEntity> selectMyselfProcessList(ActCnHistoricProcessEntity actCnHistoricProcessEntity, boolean taskIsFinished, boolean processIsfinished) {
		List<HistoricTaskInstance> tasks = null;
		Set<String> processInstanceIds = new HashSet<String>();
		Map<String,String> processInstanceIdsToTaskId = Maps.newHashMap();
		HistoricTaskInstanceQuery taskQuery = processEngine.getHistoryService().createHistoricTaskInstanceQuery();
		boolean unsend = false;
		if (!taskIsFinished && !processIsfinished) {// 环节待办，流程未结束 (代发)
			tasks = taskQuery.unfinished().processUnfinished().list();
			unsend = true;
		} else if (taskIsFinished && !processIsfinished) {// 环节已办，流程未结束(已发)
			tasks = taskQuery.finished().processUnfinished().list();
		} else if (taskIsFinished && processIsfinished) {// 环节已办，流程结束(已办结)
			tasks = taskQuery.finished().processFinished().list();
		}
		IPage<ActCnHistoricProcessEntity> page = new Page<>(actCnHistoricProcessEntity.getPage(),actCnHistoricProcessEntity.getLimit());
		// 从指定的未完成任务且流程未结束的流程实例ID中查询，如果没有则结束查询
		if (ToolUtils.isEmpty(tasks)) {
			return page;
		}
		for (HistoricTaskInstance hisTask:tasks) {
			if(unsend && (String.valueOf(AuthUtils.getCurrentUserId()).equals(hisTask.getAssignee()) || "$INITIATOR".equals(hisTask.getAssignee()))) {
				processInstanceIds.add(hisTask.getProcessInstanceId());
				processInstanceIdsToTaskId.put(hisTask.getProcessInstanceId(), hisTask.getId());
			}
			if(!unsend) {
				processInstanceIds.add(hisTask.getProcessInstanceId());
				processInstanceIdsToTaskId.put(hisTask.getProcessInstanceId(), hisTask.getId());
			}
		}
		if(processInstanceIds.size()==0) {
			return page;
		}
		HistoricProcessInstanceQuery processQuery = processEngine.getHistoryService()
				.createHistoricProcessInstanceQuery().startedBy(String.valueOf(AuthUtils.getCurrentUserId()));
		processQuery.processInstanceIds(processInstanceIds);
		if (ToolUtils.isNotEmpty(actCnHistoricProcessEntity.getName())) {
			processQuery.processInstanceNameLike("%" + actCnHistoricProcessEntity.getName() + "%");
		}
		int total = (int) processQuery.count();
		if(total==0) {
			return page;
		}
		page.setTotal(total);
		List<HistoricProcessInstance> list = processQuery.orderByProcessInstanceStartTime().desc().listPage(actCnHistoricProcessEntity.getStart(),actCnHistoricProcessEntity.getLimit());
		List<ActCnHistoricProcessEntity> records = new ArrayList<ActCnHistoricProcessEntity>();
		for(HistoricProcessInstance entity:list) {
			ActCnHistoricProcessEntity tmpProcess = new ActCnHistoricProcessEntity(entity);
			tmpProcess.setTaskId(processInstanceIdsToTaskId.get(entity.getId()));
			records.add(tmpProcess);
		}
		page.setRecords(records);
		return page;
	}

	/**
	 * 查询历史流程任务
	 */
	private IPage<ActCnHistoricProcessEntity> selectHistoricProcessList(ActCnHistoricProcessEntity actCnHistoricProcessEntity, boolean taskIsFinished) {
		List<HistoricTaskInstance> tasks = null;
		Set<String> processInstanceIds = new HashSet<String>();
		Map<String,String> processInstanceIdsToTaskId = Maps.newHashMap();
		HistoricTaskInstanceQuery taskQuery = processEngine.getHistoryService().createHistoricTaskInstanceQuery();

		if (!taskIsFinished && !AuthUtils.isAdministration()) {// 环节待办
			tasks = taskQuery.taskAssignee(String.valueOf(AuthUtils.getCurrentUserId())).unfinished().processUnfinished().list();
		} else if (taskIsFinished && !AuthUtils.isAdministration()) {// 环节已办
			tasks = taskQuery.taskAssignee(String.valueOf(AuthUtils.getCurrentUserId())).finished().list();
		} else if (!taskIsFinished && AuthUtils.isAdministration()) {// 环节待办，管理员
			tasks = taskQuery.unfinished().processUnfinished().list();
		} else if (taskIsFinished && AuthUtils.isAdministration()) {// 环节已办，管理员
			tasks = taskQuery.finished().list();
		}
		IPage<ActCnHistoricProcessEntity> page = new Page<>(actCnHistoricProcessEntity.getPage(),actCnHistoricProcessEntity.getLimit());
		if (ToolUtils.isEmpty(tasks)) {
			return page;
		}
		for (HistoricTaskInstance hisTask:tasks) {
			// 排除自己发起，自己提交的任务流程 
			HistoricProcessInstance instance = processEngine.getHistoryService()
					.createHistoricProcessInstanceQuery().processInstanceId(hisTask.getProcessInstanceId())
					.singleResult();
			if (null != instance && instance.getStartUserId().equals(String.valueOf(AuthUtils.getCurrentUserId()))) {
				continue;
			}
			processInstanceIdsToTaskId.put(hisTask.getProcessInstanceId(), hisTask.getId());
			processInstanceIds.add(hisTask.getProcessInstanceId());
		}
		// 从指定的未完成任务且流程未结束的流程实例ID中查询，如果没有则结束查询
		if (ToolUtils.isEmpty(processInstanceIds)) {
			return page;
		}
		HistoricProcessInstanceQuery processQuery = processEngine.getHistoryService().createHistoricProcessInstanceQuery();
		processQuery.processInstanceIds(processInstanceIds);
		if (ToolUtils.isNotEmpty(actCnHistoricProcessEntity.getName())) {
			processQuery.processInstanceNameLike("%" + actCnHistoricProcessEntity.getName() + "%");
		}
		int total = (int) processQuery.count();
		if(total==0) {
			return page;
		}
		page.setTotal(total);
		List<HistoricProcessInstance> list = processQuery.orderByProcessInstanceStartTime().desc().listPage(actCnHistoricProcessEntity.getStart(),actCnHistoricProcessEntity.getLimit());
		List<ActCnHistoricProcessEntity> records = new ArrayList<ActCnHistoricProcessEntity>();
		for(HistoricProcessInstance entity:list) {
			ActCnHistoricProcessEntity tmpProcess = new ActCnHistoricProcessEntity(entity);
			tmpProcess.setTaskId(processInstanceIdsToTaskId.get(entity.getId()));
			records.add(tmpProcess);
		}
		page.setRecords(records);
		return page;
	}
	
	/**
	 * 启动第一个节点任务
	 */
	@Transactional
	public void completeFirstTask(String taskId) {
		processEngine.getTaskService().complete(taskId);
	}
	
	/**
	 * 审批任务
	 */
	@Transactional
	public boolean completeTask(CompleteTask completeTask) {
		String taskId = completeTask.getTaskId();
		String processInstanceId = completeTask.getProcessInstanceId();
		String comment = ToolUtils.toStr(completeTask.getComment(), "同意");
		//1.查看当前任务是存在
		TaskEntity taskEntity = (TaskEntity) processEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		if (taskEntity == null) {
			return false;
		}
		//3.任务变量
		Map<String, Object> variables = completeTask.getVariables();
		if (variables == null) {// 创建变量
			variables = Maps.newHashMap();
		}
		variables.put(FlowableConstants.AGREE_OR_REFUSE, completeTask.getAgree());
		//4.生成审批意见
		processEngine.getTaskService().addComment(taskId, processInstanceId, comment);
		//5.附件
		List<FlowAttachment> attachments = completeTask.getAttachments();
		if(attachments!=null){
			for(FlowAttachment attachment : attachments){
				processEngine.getTaskService().createAttachment(attachment.getAttachmentType(),
						taskId,processInstanceId,attachment.getAttachmentName(),attachment.getAttachmentDescription(),
						attachment.getUrl());
			}
		}
		//6.委派处理
		if (DelegationState.PENDING.equals(taskEntity.getDelegationState())) {
			//6.1执行委派
			processEngine.getTaskService().resolveTask(completeTask.getTaskId(), variables);
			//6.2生成历史记录
			TaskEntity task = this.createSubTask(taskEntity,taskEntity.getId(),String.valueOf(AuthUtils.getCurrentUserId()));
			processEngine.getTaskService().complete(task.getId());
		} else {
			//6.1完成任务
			processEngine.getTaskService().complete(completeTask.getTaskId(), variables);
			//6.2 处理加签父任务
			String parentTaskId = taskEntity.getParentTaskId();
			if (StringUtils.isNotBlank(parentTaskId)) {
				String tableName = managementService.getTableName(TaskEntity.class);
				String sql = "select count(1) from " + tableName + " where parent_task_id_=#{parentTaskId}";
				long subTaskCount = processEngine.getTaskService().createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).count();
				if (subTaskCount == 0) {
					Task task = processEngine.getTaskService().createTaskQuery().taskId(parentTaskId).singleResult();
					//处理前后加签的任务
					processEngine.getTaskService().resolveTask(parentTaskId);
					if (FlowableConstants.AFTER_ADDSIGN.equals(task.getScopeType())) {
						processEngine.getTaskService().complete(parentTaskId);
					}
				}
			}
		}
		return true;
	}

	/**
	 * 根据Id启动流程
	 */
	@Transactional
	public String startProcessInstanceByDeployId(String deployId, String businessKey, String processName, Map<String, Object> variables) {
		// 设置流程启动用户
		processEngine.getIdentityService().setAuthenticatedUserId(String.valueOf(AuthUtils.getCurrentUserId()));
		ProcessInstanceBuilder processInstanceBuilder = processEngine.getRuntimeService().createProcessInstanceBuilder();
		ProcessDefinition processDefinition = processEngine.getRepositoryService().createProcessDefinitionQuery().deploymentId(deployId).latestVersion().singleResult();
		if(ToolUtils.isBlank(processName)){
			processName = AuthUtils.getCurrentUserName() + "发起的" + processDefinition.getName();
		}
		processInstanceBuilder.processDefinitionId(processDefinition.getId()).businessKey(businessKey).variables(variables).name(processName);
		// 开启流程
		ProcessInstance processInstance = processInstanceBuilder.start();
		return processInstance.getId();
	}

	/**
	 * 根据key启动流程
	 */
	@Transactional
	public String startProcessInstanceByKey(String processDefinitionKey, String businessKey, String processName, Map<String, Object> variables) {
		// 设置流程启动用户
		processEngine.getIdentityService().setAuthenticatedUserId(String.valueOf(AuthUtils.getCurrentUserId()));
		ProcessInstanceBuilder processInstanceBuilder = processEngine.getRuntimeService().createProcessInstanceBuilder();
		ProcessDefinition processDefinition = processEngine.getRepositoryService().createProcessDefinitionQuery().processDefinitionKey(processDefinitionKey).latestVersion().singleResult();
		if(ToolUtils.isBlank(processName)){
			processName = AuthUtils.getCurrentUserName() + "发起的" + processDefinition.getName();
		}
		// 开启流程
		processInstanceBuilder.processDefinitionKey(processDefinitionKey).businessKey(businessKey).variables(variables).name(processName);
		ProcessInstance processInstance = processInstanceBuilder.start();
		return processInstance.getId();
	}
	
	/**
	 * 根据部署id启动流程并处理
	 */
	public String startProcessInstanceAndSendTaskById(String deployId, String businessKey,String processName,Map<String, Object> variables) {
		String processInstanceId = startProcessInstanceByDeployId(deployId,businessKey,processName,variables);
		Task task = processEngine.getTaskService().createTaskQuery().processInstanceId(processInstanceId).active().singleResult();
		if(task==null) {
			log.warn("流程的当前任务不需要处理");
			return processInstanceId;
		}
		this.completeFirstTask(task.getId());
		return processInstanceId;
	}

	/**
	 * 流程终止
	 */
	@Transactional
	public boolean stopProcessInstanceById(StopProcessInstance stopProcessInstance) {
		ProcessInstance processInstance = processEngine.getRuntimeService().createProcessInstanceQuery()
				.processInstanceId(stopProcessInstance.getProcessInstanceId()).active().singleResult();
		if(processInstance==null) {
			throw new MoonException("流程实例不存在");
		}
		// 增加评论
		if (ToolUtils.isNoneBlank(stopProcessInstance.getTaskId())) {
			String comment = ToolUtils.toStr(stopProcessInstance.getComment(), "流程终止");
			processEngine.getTaskService().addComment(stopProcessInstance.getTaskId(), stopProcessInstance.getProcessInstanceId(), comment);
		}
		
		List<EndEvent> endNodes = flowableBpmnModelService.findEndFlowElement(processInstance.getProcessDefinitionId());
		String endId = endNodes.get(0).getId();
		//2、执行终止
		List<Execution> executions = processEngine.getRuntimeService().createExecutionQuery().parentId(stopProcessInstance.getProcessInstanceId()).list();
		List<String> executionIds = new ArrayList<>();
		executions.forEach(execution -> executionIds.add(execution.getId()));
		processEngine.getRuntimeService().createChangeActivityStateBuilder()
				.moveExecutionsToSingleActivityId(executionIds, endId)
				.changeState();
		return true;
	}

	/**
	 * 流程撤回
	 * 撤回一定是当前这个用户最近的一次完成的任务
	 */
	@Transactional
	public boolean revokeProcess(RevokeProcessTask revokeProcessTask,String taskDefinitionKey) {
		String processInstanceId = revokeProcessTask.getProcessInstanceId();
		//1.设置提交人
		processEngine.getRuntimeService().setVariable(processInstanceId, "revokeProcessUser", AuthUtils.getCurrentUserId());
		//2.删除运行和历史的节点信息
		processEngine.getHistoryService().deleteHistoricTaskInstance(revokeProcessTask.getTaskId());
		this.deleteActivity(taskDefinitionKey, processInstanceId);
		//3.执行跳转
		List<Execution> executions = processEngine.getRuntimeService().createExecutionQuery().parentId(processInstanceId).list();
		List<String> executionIds = new ArrayList<>();
		executions.forEach(execution -> executionIds.add(execution.getId()));
		processEngine.getRuntimeService().createChangeActivityStateBuilder()
				.moveExecutionsToSingleActivityId(executionIds, taskDefinitionKey)
				.changeState();

		//4.成功撤回之后，就执行签收操作(暂时不签收)
		Task newTask = processEngine.getTaskService().createTaskQuery().processInstanceId(processInstanceId).active().singleResult();
		String comment = ObjectUtils.isEmpty(revokeProcessTask.getComment())?"流程撤回":revokeProcessTask.getComment();
		//5.增加评论
		if (ToolUtils.isNoneBlank(processInstanceId, comment)) {
			processEngine.getTaskService().addComment(newTask.getId(), processInstanceId, comment);
		}
		return true;
	}
	
	/**
	 * 转办
	 */
	@Transactional
	public boolean turnTask(TurnTask turnTask) {
		String taskId = turnTask.getTaskId();
		String processInstanceId = turnTask.getProcessInstanceId();
		String comment = ToolUtils.toStr(turnTask.getComment(), "流程转办");
		TaskEntityImpl currTask = (TaskEntityImpl) processEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		if (currTask == null) {
			return false;
		}
		//1.生成历史记录
		TaskEntity task = this.createSubTask(currTask,currTask.getId(), String.valueOf(AuthUtils.getCurrentUserId()));
		//2.添加审批意见
		processEngine.getTaskService().addComment(taskId, processInstanceId, comment);
		processEngine.getTaskService().complete(task.getId());
		//3.转办
		processEngine.getTaskService().setAssignee(turnTask.getTaskId(), String.valueOf(turnTask.getTurnToUserId()));
		processEngine.getTaskService().setOwner(turnTask.getTaskId(), String.valueOf(AuthUtils.getCurrentUserId()));
		return true;
	}

	/**
	 * 委托
	 */
	@Transactional
	public boolean delegateTask(DelegateTask delegateTask) {
		String processInstanceId = delegateTask.getProcessInstanceId();
		String comment = ToolUtils.toStr(delegateTask.getComment(), "流程转办");
		TaskEntityImpl currTask = (TaskEntityImpl) processEngine.getTaskService().createTaskQuery().taskId(delegateTask.getTaskId()).singleResult();
		if (currTask == null) {
			return false;
		}
		//1.添加审批意见
		processEngine.getTaskService().addComment(delegateTask.getTaskId(), processInstanceId, comment);
		//2.设置审批人就是当前登录人
		processEngine.getTaskService().setAssignee(delegateTask.getTaskId(), String.valueOf(delegateTask.getUserId()));
		//3.执行委派
		processEngine.getTaskService().delegateTask(delegateTask.getTaskId(), String.valueOf(delegateTask.getDelegateUserId()));
		return true;
	}

	/**
	 * 向前加签
	 */
	@Transactional
	public void beforeAddSignTask(AddSignTask addSignTask){
		this.addSignTask(addSignTask,false);
	}

	/**
	 * 向后加签
	 */
	@Transactional
	public void afterAddSignTask(AddSignTask addSignTask){
		this.addSignTask(addSignTask,true);
	}

	private void addSignTask(AddSignTask addSignTask, Boolean flag) {
		TaskEntityImpl taskEntity = (TaskEntityImpl) processEngine.getTaskService().createTaskQuery().taskId(addSignTask.getTaskId()).singleResult();
		//1.把当前的节点设置为空
		if (taskEntity == null) {
			return;
		}
		//如果是加签再加签
		String parentTaskId = taskEntity.getParentTaskId();
		if (StringUtils.isBlank(parentTaskId)) {
			taskEntity.setOwner(String.valueOf(addSignTask.getSignPersoned()));
			taskEntity.setAssignee(null);
			taskEntity.setCountEnabled(true);
			if (flag) {
				taskEntity.setScopeType(FlowableConstants.AFTER_ADDSIGN);
			} else {
				taskEntity.setScopeType(FlowableConstants.BEFORE_ADDSIGN);
			}
			//1.2 设置任务为空执行者
			processEngine.getTaskService().saveTask(taskEntity);
		}
		//2.添加加签数据
		this.createSignSubTasks(addSignTask, taskEntity);
		//3.添加审批意见
		String type = flag ? "后加签" : "前加签";
		processEngine.getTaskService().addComment(addSignTask.getTaskId(),addSignTask.getProcessInstanceId(),type, addSignTask.getComment());
	}

	/**
	 * 创建加签子任务
	 * @param addSignTask     加签参数
	 * @param taskEntity 父任务
	 */
	private void createSignSubTasks(AddSignTask addSignTask, TaskEntity taskEntity) {
		String parentTaskId = taskEntity.getParentTaskId();
		if (StringUtils.isBlank(parentTaskId)) {
			parentTaskId = taskEntity.getId();
		}
		String finalParentTaskId = parentTaskId;
		//1.创建被加签人的任务列表
		if(ToolUtils.isNotEmpty(addSignTask.getSignPersoneds())){//同时加签多人
			addSignTask.getSignPersoneds().forEach(userCode -> {
				this.createSubTask(taskEntity, finalParentTaskId, String.valueOf(userCode));
			});
		}else{
			this.createSubTask(taskEntity, finalParentTaskId, String.valueOf(addSignTask.getSignPersoned()));
		}
		String taskId = taskEntity.getId();
		if (StringUtils.isBlank(taskEntity.getParentTaskId())) {
			//2.创建加签人的任务并执行完毕
			Task task = this.createSubTask(taskEntity, finalParentTaskId, String.valueOf(addSignTask.getSignPersoned()));
			taskId = task.getId();
		}
		Task taskInfo = processEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		if (null != taskInfo) {
			processEngine.getTaskService().complete(taskId);
		}
		//如果是候选人，需要删除运行时候选表种的数据。
		long candidateCount = processEngine.getTaskService().createTaskQuery().taskId(parentTaskId).taskCandidateUser(String.valueOf(addSignTask.getSignPersoned())).count();
		if (candidateCount > 0) {
			processEngine.getTaskService().deleteCandidateUser(parentTaskId, String.valueOf(addSignTask.getSignPersoned()));
		}
	}

	/**
	 * 创建子任务
	 */
	private TaskEntity createSubTask(TaskEntity ptask,String parentTaskId,String assignee) {
		TaskEntity task = (TaskEntity) processEngine.getTaskService().newTask(ToolUtils.getLowerUUID());
		task.setCategory(ptask.getCategory());
		task.setDescription(ptask.getDescription());
		task.setTenantId(ptask.getTenantId());
		task.setAssignee(assignee);
		task.setName(ptask.getName());
		task.setParentTaskId(parentTaskId);
		task.setProcessDefinitionId(ptask.getProcessDefinitionId());
		task.setProcessInstanceId(ptask.getProcessInstanceId());
		task.setTaskDefinitionKey(ptask.getTaskDefinitionKey());
		task.setTaskDefinitionId(ptask.getTaskDefinitionId());
		task.setPriority(ptask.getPriority());
		task.setCreateTime(new Date());
		processEngine.getTaskService().saveTask(task);
		return task;
	}

	/**
	 * 删除跳转的历史节点信息
	 * @param disActivityId     跳转的节点id
	 * @param processInstanceId 流程实例id
	 */
	private void deleteActivity(String disActivityId, String processInstanceId) {
		String tableName = managementService.getTableName(ActivityInstanceEntity.class);
		String sql = "select t.* from " + tableName + " t where t.PROC_INST_ID_=#{processInstanceId} and t.ACT_ID_ = #{disActivityId} " +
				" order by t.END_TIME_ ASC";
		List<ActivityInstance> disActivities = processEngine.getRuntimeService().createNativeActivityInstanceQuery().sql(sql)
				.parameter("processInstanceId", processInstanceId)
				.parameter("disActivityId", disActivityId).list();
		//删除运行时和历史节点信息
		if (ToolUtils.isNotEmpty(disActivities)) {
			ActivityInstance activityInstance = disActivities.get(0);
			sql = "select t.* from " + tableName + " t where t.PROC_INST_ID_=#{processInstanceId} and (t.END_TIME_ >= #{endTime} or t.END_TIME_ is null)";
			List<ActivityInstance> datas = processEngine.getRuntimeService().createNativeActivityInstanceQuery().sql(sql).parameter("processInstanceId", processInstanceId)
					.parameter("endTime", activityInstance.getEndTime()).list();
			List<String> runActivityIds = new ArrayList<>();
			if (ToolUtils.isNotEmpty(datas)) {
				datas.forEach(ai -> runActivityIds.add(ai.getId()));
				runFlowableActinstDao.deleteRunActinstsByIds(runActivityIds);
				hisFlowableActinstDao.deleteHisActinstsByIds(runActivityIds);
			}
		}
	}
}